package com.zjny.util;

import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Json工具类
 * 1: 将对象转换为JSON字符串{@link JsonUtils#toJsonString(Object)}
 * 2: 将JSON字符串转换为对象{@link JsonUtils#parseObject(String, Class)}
 * 3: 将JSON字符串转换为Map对象{@link JsonUtils#parseMap(String)}
 * 4: 将JSON字符串转换为ArrayMap对象{@link JsonUtils#parseArrayMap(String)}
 * 5: 将JSON字符串转换为ArrayList对象{@link JsonUtils#parseArray(String, Class)}
 * 6: 读取json文件转对象{@link JsonUtils#readJsonFileToObject(String, Class)}
 * 7: 将字节数据解析成指定类型的对象{@link JsonUtils#parseObject(byte[], Class)}
 *
 * @author cui haida
 * 2025/06/18/14:26
 */
public class JsonUtils extends JSONUtil {

    /**
     * 将对象转换为JSON字符串。
     *
     * @param object 需要转换为JSON字符串的对象。可以是任意类型的对象。
     * @return 返回对象的JSON字符串表示。如果输入对象为null，则返回null。
     * @throws RuntimeException 如果对象转换为JSON字符串时发生错误，则抛出运行时异常。
     */
    public static String toJsonString(Object object) {
        // 检查对象是否为null
        if (ObjectUtil.isNull(object)) {
            return null;
        }
        return JSON.toJSONString(object);
    }

    /**
     * 读取json文件转对象
     *
     * @param path  项目根目录下的路径
     * @param clazz 要转成的类型
     * @return 转换后的对象
     */
    public static <T> T readJsonFileToObject(String path, Class<T> clazz) {
        path = Objects.requireNonNull(FileUtils.class.getResource(path)).getFile();
        File file = new File(path);
        try {
            String data = org.apache.commons.io.FileUtils.readFileToString(file);
            return JSON.parseObject(data, clazz);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 将JSON字符串解析成指定类型的对象。
     *
     * @param text  要解析的JSON字符串。
     * @param clazz 需要解析成的目标对象的类型。
     * @return 解析成功的对象实例，如果输入字符串为空则返回null。
     * @throws RuntimeException 当JSON解析过程中发生IOException时抛出。
     */
    public static <T> T parseObject(String text, Class<T> clazz) {
        // 检查输入字符串是否为空
        if (StringUtils.isEmpty(text)) {
            return null;
        }
        return JSON.parseObject(text, clazz);
    }

    /**
     * 将字节数据解析成指定类型的对象。
     *
     * @param bytes 待解析的字节数据，如果为空则返回null。
     * @param clazz 需要解析成的对象类型。
     * @return 解析后的对象实例，如果输入字节数据为空，则返回null。
     * @throws RuntimeException 如果解析过程中发生IOException。
     */
    public static <T> T parseObject(byte[] bytes, Class<T> clazz) {
        // 检查输入的字节数据是否为空
        if (ArrayUtil.isEmpty(bytes)) {
            return null;
        }
        return JSON.parseObject(bytes, clazz);
    }

    /**
     * 将传入的字符串解析为Dict对象。
     *
     * @param text 需要解析的字符串。要求是合法的JSON格式字符串。
     * @return 如果解析成功，返回一个Dict对象；如果输入字符串为空、不是JSON格式或解析过程中发生错误，则返回null。
     */
    public static Dict parseMap(String text) {
        // 检查输入字符串是否为空或只包含空白字符
        if (StringUtils.isBlank(text)) {
            return null;
        }
        return JSON.parseObject(text, Dict.class);
    }


    /**
     * 解析字符串形式的数组映射到Dict类型的列表。
     *
     * @param text 表示待解析的字符串，应为JSON数组格式，每个元素符合Dict类型的结构。
     * @return 返回解析后的Dict类型列表。如果输入文本为空或格式不正确，则返回null或抛出异常。
     * @throws RuntimeException 当解析过程中发生IOException时抛出此异常。
     */
    public static List<Dict> parseArrayMap(String text) {
        // 检查输入文本是否为空
        if (StringUtils.isBlank(text)) {
            return null;
        }
        return JSON.parseArray(text, Dict.class);
    }


    /**
     * 将JSON字符串解析为指定类型的元素列表。
     *
     * @param text  要解析的JSON字符串。
     * @param clazz 指定的元素类型，解析结果将以此类型为准。
     * @return 解析出的元素列表，如果输入字符串为空，则返回一个空列表。
     * @throws RuntimeException 如果解析过程中发生IOException。
     */
    public static <T> List<T> parseArray(String text, Class<T> clazz) {
        // 检查输入字符串是否为空，为空则直接返回空列表
        if (StringUtils.isEmpty(text)) {
            return new ArrayList<>();
        }
        return JSON.parseArray(text, clazz);
    }
}
